/**
 * ThirdPartyValidatorFactory.java
 * author: yujiakui
 * 2017年8月29日
 * 上午11:18:05
 */
package com.ctim.service.integration.validator;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.ctim.common.exception.PcsRunTimeException;
import com.ctim.service.enums.ValidatorTypeEnum;
import com.google.common.collect.Maps;

/**
 * @author yujiakui
 *
 *         上午11:18:05
 *
 */
@Component
public class ThirdPartyValidatorFactory implements ApplicationContextAware, InitializingBean {

	/** spring 上下文 */
	private ApplicationContext applicationContext;

	/** 校验器保存map */
	private static Map<ValidatorTypeEnum, ThirdPartyResponseValidator> validatorMap = Maps.newHashMap();

	/**
	 * 根据类型获取对应的校验器
	 *
	 * @param type
	 * @return
	 */
	public static ThirdPartyResponseValidator getValidatorByType(ValidatorTypeEnum type) {
		ThirdPartyResponseValidator thirdPartyResponseValidator = validatorMap.get(type);
		if (null == thirdPartyResponseValidator) {
			throw new PcsRunTimeException(MessageFormat.format("类型type={0}对应的校验器不存在map={1}", type, validatorMap));
		}
		return thirdPartyResponseValidator;
	}

	/*
	 *
	 * @see
	 * org.springframework.context.ApplicationContextAware#setApplicationContext
	 * (org.springframework.context.ApplicationContext)
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;

	}

	/*
	 *
	 * @see
	 * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		// 获取实现validator接口的bean，然后将这种bean注入到工厂的map中
		Map<String, ThirdPartyResponseValidator> validatorMap = applicationContext
				.getBeansOfType(ThirdPartyResponseValidator.class);
		// 防止并发情况注入
		Map<ValidatorTypeEnum, ThirdPartyResponseValidator> tempValidatorMap = Maps.newHashMap(this.validatorMap);
		for (Map.Entry<String, ThirdPartyResponseValidator> entryEle : validatorMap.entrySet()) {
			ThirdPartyResponseValidator thirdPartyResponseValidator = entryEle.getValue();
			List<ValidatorTypeEnum> validatorTypeEnums = thirdPartyResponseValidator.getValidatorTypes();
			for (ValidatorTypeEnum validatorTypeEnum : validatorTypeEnums) {
				ThirdPartyResponseValidator tempValidator = tempValidatorMap.get(validatorTypeEnum);
				if (null != tempValidator) {
					if (!tempValidator.equals(thirdPartyResponseValidator)) {
						throw new PcsRunTimeException(MessageFormat.format("在校验器工厂中进行注入得到同一个type={0}对应多个校验器对象={1},{2}",
								validatorTypeEnum, thirdPartyResponseValidator, tempValidator));
					}
				} else {
					tempValidatorMap.put(validatorTypeEnum, thirdPartyResponseValidator);
				}
			}

		}

		this.validatorMap = tempValidatorMap;
	}

}
